﻿using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace HurricanePackage
{
    public class UGUIClickListener : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IMoveHandler
    {
        //最后点击的游戏帧数
        private static long g_lastClickFrame;
        [Header("长按事件的时间")] public float longPressTime = 0.5f;
        [Header("移动是否可以取消长按")] public bool isMoveCancelPress = true;
        [Header("连点限制帧数(0为取消限制)")] public int clickLimitFrame = 3;
        
        
        private Action<PointerEventData> m_actClick;//点击事件
        private Action<PointerEventData> m_actLongPressClick;//长按事件

        private float m_longPressTriggerTime;//长按目标时间
        private bool m_isLongPressTriggered = false;//长按事件是否已经触发
        private PointerEventData m_pointDownEventData;//按钮按下时的事件数据
        
        private bool m_isPointDown = false;//是否按下
        private bool m_isMove = false;//是否移动


        private void Update()
        {
            //组件无效或者长按事件已经触发
            if (!Interactable || m_isLongPressTriggered)
                return;
            if (!m_isPointDown) //按钮位处于按下状态不处理长按事件
                return;
            if (Time.unscaledTime >= m_longPressTriggerTime)
            {
                //设置长按事件标志位
                m_isLongPressTriggered = true;
                //执行长按回调
                m_actLongPressClick?.Invoke(m_pointDownEventData);
            }

        }


        //获取是否可操作 
        protected bool Interactable
        {
            get
            {
                //判断是否可操作
                Selectable selectableMono = GetComponent<Selectable>();
                if (null != selectableMono && !selectableMono.interactable)
                    return false;

                return true;
            }
        }
        /// <summary>
        /// 获取listener
        /// </summary>
        public static UGUIClickListener Get(GameObject _go)
        {
            if (_go == null)
                return null;

            UGUIClickListener listener = _go.GetComponent<UGUIClickListener>();
            if (listener == null)
                listener = _go.AddComponent<UGUIClickListener>();
            return listener;
        }
        /// <summary>
        /// 移除listener
        /// </summary>
        public static void RemoveListener(GameObject _go)
        {
            if (_go == null)
                return;
            UGUIClickListener listener = _go.GetComponent<UGUIClickListener>();
            if(listener != null)
                Destroy(listener);
        }
        public void RemoveListener()
        {
            Destroy(this);
        }
        
        
        //单击事件
        public void RegisterUIClick(Action<PointerEventData> _action)
        {
            if (m_actClick == null)
                m_actClick = _action;
            else
            {
                m_actClick += _action;
            }
        }
        public void UnRegisterUIClick(Action<PointerEventData> _action)
        {
            if (m_actClick == null)
                m_actClick = _action;
            else
            {
                m_actClick += _action;
            }
        }
        //长按事件
        public void RegisterUILongPress(Action<PointerEventData> _action)
        {
            if (m_actLongPressClick == null)
                m_actLongPressClick = _action;
            else
            {
                m_actLongPressClick += _action;
            }
        }
        public void UnRegisterUILongPress(Action<PointerEventData> _action)
        {
            if (m_actLongPressClick == null)
                m_actLongPressClick = _action;
            else
            {
                m_actLongPressClick += _action;
            }
        }
        

        #region 接口实现 

        public void OnPointerClick(PointerEventData _eventData)
        {
            //组件无效或者 长按事件触发
            if(!Interactable || m_isLongPressTriggered )
                return;
            //连点限制处理
            if (clickLimitFrame > 0)
            {
                long offset = Time.frameCount - g_lastClickFrame;
                if (clickLimitFrame <= offset)//间隔帧数大于限制时执行回调
                    m_actClick?.Invoke(_eventData);
            }
            else
            {
                m_actClick?.Invoke(_eventData);
            }
            
            //记录点击帧数
            g_lastClickFrame = Time.frameCount;
        }

   
        public void OnPointerDown(PointerEventData _eventData)
        {
            if(!Interactable)
                return;
            m_isMove = false;
            m_isPointDown = true;
            
            
            //重置长按事件标志位
            m_isLongPressTriggered = false;
            //设置长按触发的时间
            m_longPressTriggerTime = Time.unscaledTime + longPressTime;
           //保存按下时的事件数据
            m_pointDownEventData = _eventData;
        }

        public void OnPointerUp(PointerEventData _eventData)
        {
            m_isPointDown = false;
            m_isMove = false;

            //抬起时清空按下的保存数据
            m_pointDownEventData = null;
            //重置长按事件标志位
            //m_isLongPressTriggered = false;//避免执行到click的回调
        }

        public void OnMove(AxisEventData eventData)
        {
            m_isMove = true;
        }
        #endregion


    }
}

